﻿using DotNetStar.TheKing.Infrastructure;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Caching.Memory;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading;

namespace DotNetStar.TheKing.Services
{
    /// <summary>
    /// 验证码服务
    /// </summary>
    public class VerifyCodeService
    {
        private readonly IHostingEnvironment _environment;
        private IMemoryCache _cache;
        private readonly NotificationSchedular _notification;
        public VerifyCodeService(IHostingEnvironment environment,IMemoryCache cache, NotificationSchedular notification)
        {
            this._environment = environment;
            _cache = cache;
            this._notification = notification;
        }

        /// <summary>
        /// 获取验证码；优先从缓存中读取，若缓存中无该验证码，则会新增一个缓存。
        /// <see cref="IDebug"/> 是 <see cref="Debug"/> 状态时，验证码固定123456。
        /// </summary>
        /// <param name="key">缓存的键。</param>
        /// <returns>验证码字符串。</returns>
        string GenerateCode(string key)
        {

            var code= _cache.GetOrCreate(key, (entry) =>
            {
                entry.SetAbsoluteExpiration(DateTimeOffset.Now.AddMinutes(5));
                entry.SetSlidingExpiration(TimeSpan.FromMinutes(5));
                var verifyCode = new Random().Next(100000, 999999).ToString();
                if (_environment.IsDevelopment())
                {
                    verifyCode = "123456";
                }
                return verifyCode;
            });
            return code;
        }

        /// <summary>
        /// 验证指定输入的验证码。
        /// </summary>
        /// <param name="key">缓存中存储的键。</param>
        /// <param name="inputCode">输入的验证码。</param>
        /// <returns>若匹配则返回 <c>true</c>；否则返回 <c>false</c>。</returns>
        public virtual bool VerifyCode(string key, string inputCode)
        {
            if (_cache.TryGetValue(key, out string value))
            {
                if(value == inputCode)
                {
                    _cache.Remove(key);
                    return true;
                }
                return false;
            }
            return false;
        }

        /// <summary>
        /// 将生成的验证码放入队列中，由调度中心进行发送
        /// </summary>
        /// <param name="receiver">验证码接收帐号，手机/邮箱</param>
        /// <param name="type">发送类型</param>
        public virtual void PutVerifyCode(string receiver, AccountTypes type)
        {
            var code = GenerateCode(receiver);

            switch (type)
            {
                case AccountTypes.Email:
                    _notification.CreateNotification(EmailNotification.SendVerifyCode(receiver, code));
                    break;
                case AccountTypes.Mobile:
                    _notification.CreateNotification(SmsNotification.SendVerifyCode(receiver, code));
                    break;
                default:
                    break;
            }
        }

      
    }
}
